package com.hkts.management.contract.service.serviceimpl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hkts.management.cargo.entity.HktsCargo;
import com.hkts.management.cargo.mapper.HktsCargoMapper;
import com.hkts.management.common.mq.*;
import com.hkts.management.common.utils.BeanConvertUtils;
import com.hkts.management.common.utils.Result;
import com.hkts.management.common.utils.ResultUtil;
import com.hkts.management.common.utils.SnowFlakeUtil;
import com.hkts.management.common.vo.UserAndRealNameVo;
import com.hkts.management.contract.entity.HktsContract;
import com.hkts.management.contract.service.IHktsContractService;
import com.hkts.management.contract.mapper.HktsContractMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.management.es.EsSearchUtil;
import com.hkts.management.feign.FeignInterface;
import com.hkts.management.feign.FrontInterface;
import com.hkts.management.model.TO.HontUserTo;
import com.hkts.management.model.VO.HktsContractOnPCVo;
import com.hkts.management.model.VO.UserVo;
import com.hkts.management.model.constants.CargoListVoConstants;
import com.hkts.management.model.enums.OrderStatusEnum;
import com.hkts.management.model.enums.OrderTypeEnum;
import com.hkts.management.model.result.ResultAreaPlace;
import com.hkts.management.model.result.ResultData;
import com.hkts.management.order.entity.HktsOrder;
import com.hkts.management.order.mapper.HktsOrderMapper;
import com.hkts.management.order.service.serviceimpl.HktsOrderServiceImpl;
import com.hkts.management.order.vo.UpdateAddressInfoParameterVo;
import com.hkts.management.orderrecord.service.IHktsOrderRecordService;
import com.hkts.management.utils.AddressUtils;
import com.hkts.management.utils.RegionConverUtil;
import com.hkts.management.utils.StringUtil;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.apache.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hml
 * @since 2021-04-22
 */
@Service
@Transactional
public class HktsContractServiceImpl extends ServiceImpl<HktsContractMapper, HktsContract> implements IHktsContractService {


    @Autowired
    private HktsContractMapper hktsContractMapper;

    @Autowired
    private HktsOrderMapper orderMapper;

    @Autowired
    private HktsCargoMapper hktsCargoMapper;

    @Autowired
    private FrontInterface frontInterface;
    @Autowired
    private FeignInterface feignInterface;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private RegionConverUtil regionConverUtil;
    @Autowired
    private HktsOrderServiceImpl orderService;

    @Autowired
    private IHktsOrderRecordService iHktsOrderRecordService;

    @Override
    public IPage<HktsContract> selectPage(Page<HktsContract> page, HktsContract hktsContract) {
        QueryWrapper<HktsContract> query = Wrappers.query();
        QueryWrapper<HktsContract> entityWrapper = getEntityWrapper(query, hktsContract);
        return hktsContractMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<HktsContract> selectList(HktsContract hktsContract) {
        QueryWrapper<HktsContract> query = Wrappers.query();
        QueryWrapper<HktsContract> entityWrapper = getEntityWrapper(query, hktsContract);
        return hktsContractMapper.selectList(entityWrapper);
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<HktsContract> getEntityWrapper(QueryWrapper<HktsContract> entityWrapper, HktsContract hktsContract) {
        //条件拼接
        return entityWrapper;
    }

    /**
     * 初始化合同回显数据
     * @param orderId
     * @return
     */
    @Override
    public Map<String ,Object> getContractByOrderId(String orderId){
        QueryWrapper<HktsContract> query = Wrappers.query();
        query.lambda().eq(HktsContract::getOrderId,orderId);
        HktsContract contract = hktsContractMapper.selectOne(query);
        HktsOrder order = orderMapper.selectById(orderId);
        Result<UserVo> userByuserId = feignInterface.getUserByuserId(order.getShipper());

        String startAreaStr =  contract.getStartArea();
        String startArea = frontInterface.getRegionName(startAreaStr).getResult();
        String endAreaStr = contract.getEndArea();
        String endArea = frontInterface.getRegionName(endAreaStr).getResult();
        Map<String ,Object> totalinfo=new HashMap<>();
        //头部信息
        totalinfo.put("contractId",contract.getId());
        totalinfo.put("orderId",orderId);
        totalinfo.put("orderSubstate",order.getOrderSubstate());
        totalinfo.put("orderStatus",order.getShipperOrderStatus().getValue());
        totalinfo.put("contractStatus",contract.getContractStatus());
        //运费信息
        totalinfo.put("payTransportTotal",contract.getTransportPrice());
        if (contract.getPayTime() != null){
            totalinfo.put("payTime",contract.getPayTime());
        }else {
            totalinfo.put("payTime",1);
        }
        totalinfo.put("startCode",contract.getStartArea());
        totalinfo.put("startArea",startArea);
        totalinfo.put("startAddress",contract.getStartAddressDetail());
        totalinfo.put("startTitle",order.getStartAddress());
        totalinfo.put("startDay",contract.getLoadingTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        totalinfo.put("startTime",contract.getLoadingTime().format(DateTimeFormatter.ofPattern("HH:mm")));
        totalinfo.put("endCode",contract.getEndArea());
        totalinfo.put("endArea",endArea);
        totalinfo.put("endAddress",contract.getEndAddressDetail());
        totalinfo.put("endTitle",order.getEndAddress());
        totalinfo.put("cargoType",contract.getCargoType());
        totalinfo.put("cargoMoney",contract.getCargoPrice());
        if (StringUtils.isNotBlank(contract.getCargoType())){
            Result<Map<String, Object>> dictItemByItemId = frontInterface.getDictItemByItemId(contract.getCargoType());
            totalinfo.put("agreementId",dictItemByItemId.getResult().get("id"));
            totalinfo.put("cargoTypeName",dictItemByItemId.getResult().get("cargoTypeName"));
            totalinfo.put("agreementName",dictItemByItemId.getResult().get("agreementName"));
        }else {
            totalinfo.put("agreementId","");
            totalinfo.put("cargoTypeName","");
            totalinfo.put("agreementName","");
        }

        if (contract.getLoadingTime() != null){
            totalinfo.put("endDay",contract.getUnloadingTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            totalinfo.put("endTime",contract.getUnloadingTime().format(DateTimeFormatter.ofPattern("HH:mm")));
        }else {
            totalinfo.put("endDay",contract.getLoadingTime().plus(1, ChronoUnit.DAYS).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            totalinfo.put("endTime",contract.getLoadingTime().format(DateTimeFormatter.ofPattern("HH:mm")));
        }
        totalinfo.put("day",1);

        //货物信息
        totalinfo.put("cargoName",contract.getCargoName());
        totalinfo.put("cargoWeight",contract.getCargoWeight());
        //补充约定

        if (contract.getSupplementAgree() != null){
            totalinfo.put("supplementAgree",contract.getSupplementAgree());
        }else {
            totalinfo.put("supplementAgree","");
        }
        Map<String ,Object> userInfo=new HashMap<>();
        if (userByuserId.getResult() != null){
            userInfo.put("userName",userByuserId.getResult().getNickName());
            userInfo.put("mobile",userByuserId.getResult().getMobiles());
            userInfo.put("pushTime",contract.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }else {
            userInfo.put("userName","/");
            userInfo.put("mobile","/");
            userInfo.put("pushTime","/");
        }
        totalinfo.put("userInfo",userInfo);
        Result<UserAndRealNameVo> driverInfoByUserId = frontInterface.getDriverInfoByUserId(order.getDriverId());
        Map<String ,Object> driverInfo=new HashMap<>();
        if (driverInfoByUserId.getResult() == null){
            driverInfo.put("userName","/");
            driverInfo.put("mobile","/");
            driverInfo.put("plateNumber","/");
            driverInfo.put("pushTime","/");
        }else if(contract.getContractStatus() == 0) {
            driverInfo.put("userName",driverInfoByUserId.getResult().getDriverName());
            driverInfo.put("mobile",driverInfoByUserId.getResult().getMobile());
            driverInfo.put("plateNumber","/");
            driverInfo.put("pushTime","/");
        }else  {
            driverInfo.put("userName",driverInfoByUserId.getResult().getDriverName());
            driverInfo.put("mobile",driverInfoByUserId.getResult().getMobile());
            driverInfo.put("pushTime",order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            if(StringUtils.isBlank(contract.getCarrierPlate())){
                driverInfo.put("plateNumber",driverInfoByUserId.getResult().getCarCode());
            }else {
                driverInfo.put("plateNumber",contract.getCarrierPlate());
            }

        }
        totalinfo.put("driverInfo",driverInfo);
        totalinfo.put(CargoListVoConstants.CARTYPE,contract.getCargoType());
        return totalinfo;
    }


    @Override
    public Result<Object> updateContract(HktsContract contract){
        ResultAreaPlace startPlace = new ResultAreaPlace();
        startPlace.setAddressCode(contract.getStartArea());
        startPlace.setAddress(contract.getStartAddressDetail());
        Integer reginCodeStart = Integer.valueOf(contract.getStartArea());
        startPlace = regionConverUtil.regionCover(reginCodeStart, startPlace);
        String startArea = startPlace.getProvice() + startPlace.getCity() + startPlace.getCounty();

        ResultAreaPlace endPlace = new ResultAreaPlace();
        endPlace.setAddressCode(contract.getEndArea());
        endPlace.setAddress(contract.getEndAddressDetail());
        Integer reginCodeEnd = Integer.valueOf(contract.getEndArea());
        endPlace = regionConverUtil.regionCover(reginCodeEnd, endPlace);
        String endArea = endPlace.getProvice() + endPlace.getCity() + endPlace.getCounty();
        String lonLat = AddressUtils.getLonLat(startArea + contract.getStartAddressDetail());
        String lon = lonLat.substring(0, lonLat.indexOf(","));
        String lat = lonLat.substring(lon.length() + 1, lonLat.length());
        BigDecimal lonto = StringUtil.getbd(lon);
        BigDecimal latto = StringUtil.getbd(lat);
        contract.setStartLat(latto);
        contract.setStartLon(lonto);
        String endlonLat = AddressUtils.getLonLat(endArea + contract.getEndAddressDetail());
        String endlon = endlonLat.substring(0, endlonLat.indexOf(","));
        String endlat = endlonLat.substring(endlon.length() + 1, endlonLat.length());
        BigDecimal endlonto = StringUtil.getbd(endlon);
        BigDecimal endlatto = StringUtil.getbd(endlat);
        contract.setEndLat(endlatto);
        contract.setEndLon(endlonto);
        contract.setContractStatus(0);
        if(contract.getStartAddressDetail().endsWith(contract.getStartTitle())){
            contract.setStartAddressDetail(contract.getStartAddressDetail() );
        }else{
            contract.setStartAddressDetail(contract.getStartAddressDetail() + contract.getStartTitle());
        }
        if(contract.getEndAddressDetail().endsWith(contract.getEndTitle())){
            contract.setEndAddressDetail(contract.getEndAddressDetail());
        }else{
            contract.setEndAddressDetail(contract.getEndAddressDetail() + contract.getEndTitle());
        }
        hktsContractMapper.updateContract(contract);
        HktsContract hktsContract = hktsContractMapper.selectById(contract.getId());
        HktsOrder order=orderMapper.selectById(hktsContract.getOrderId());

        HktsCargo hktsCargo = hktsCargoMapper.selectById(order.getCargoId());
        if (contract.getCargoWeight().compareTo(hktsCargo.getCargoResidual()) == 1){
            hktsCargo.setCargoTotal(hktsCargo.getCargoTotal().add(contract.getCargoWeight().subtract(hktsCargo.getCargoResidual())));
            BigDecimal residual = new BigDecimal("0");
            hktsCargo.setCargoResidual(residual);
            hktsCargoMapper.updateCargoById(hktsCargo);
        }

        UpdateAddressInfoParameterVo addressInfoParameterVo = new UpdateAddressInfoParameterVo();
        addressInfoParameterVo.setOrderId(order.getId());
        addressInfoParameterVo.setStart(contract.getStartTitle());
        addressInfoParameterVo.setEnd(contract.getEndTitle());
        addressInfoParameterVo.setStatus(OrderTypeEnum.SIGN_CONTRACT.getValue());
        addressInfoParameterVo.setSubstate(OrderStatusEnum.SIGN_CONTRACT.getValue());
        addressInfoParameterVo.setTime(LocalDateTime.now());
        orderMapper.updateAddressInfo(addressInfoParameterVo);
        HontUserTo hontUserTo = feignInterface.remoteUserInfo();
        iHktsOrderRecordService.addOrderRecord(order.getId(),hontUserTo.getNickName(),OrderStatusEnum.SIGN_CONTRACT.getValue());
        //TODO es同步数据
        orderService.updateOrderOnEs(order.getId(), OrderTypeEnum.SIGN_CONTRACT,OrderStatusEnum.SIGN_CONTRACT.getValue());
        //发送消息
        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
            @Override
            public void afterCommit() {

                String address=regionConverUtil.regionCoverStr(Integer.valueOf(contract.getStartArea()))+"-"+regionConverUtil.regionCoverStr(Integer.valueOf(contract.getEndArea()));
                Map<String, Object> params=new HashMap<>();
                params.put("name",hontUserTo.getNickName());
                params.put("time", contract.getLoadingTime().toLocalDate());
                params.put("address",address);
                MsgExtras msgExtras=new MsgExtras();
                msgExtras.setOrderId(order.getId());
                String messageId=String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
                IMessage msg = new IMessage.Builder()
                        .messageId(messageId)
                        .msgCode(IMessage.DRAWUP_CONTRACT)
                        .fromUserId(order.getShipper())
                        .toUserId(order.getDriverId())
                        .mineType(MineType.TEMPLATE.getIndex())
                        .chatType(ChatType.UNICAST.getIndex())
                        .msgType(MsgType.JUMPTO.getIndex())
                        .param(params)
                        .extras(msgExtras)
                        .build();
                Map<?,?> msgMap= BeanConvertUtils.objectToMap(msg);
                amqpTemplate.convertAndSend(FanoutRabbitConfig.FANOUTEXCHANGE, FanoutRabbitConfig.ASSIFN, msgMap);
            }
        });
        return ResultUtil.success("起草成功");
    }

    @Override
    public HktsContractOnPCVo getContractByOrderIdOnPC(String orderId) {
        HktsOrder order=orderService.getById(orderId);
        QueryWrapper<HktsContract> query = Wrappers.query();
        query.lambda().eq(HktsContract::getOrderId,orderId);
        HktsContract contract = hktsContractMapper.selectOne(query);
        HktsContractOnPCVo hktsContractOnPCVo=BeanConvertUtils.copy(contract,HktsContractOnPCVo.class);
        ResultAreaPlace startPlace=new ResultAreaPlace();
        hktsContractOnPCVo.setStartAreaInfo( regionConverUtil.regionCover(Integer.valueOf(contract.getStartArea()),startPlace));
        ResultAreaPlace endPlace=new ResultAreaPlace();
        hktsContractOnPCVo.setEndAreaInfo(regionConverUtil.regionCover(Integer.valueOf(contract.getEndArea()),endPlace));
        hktsContractOnPCVo.setOrderSubstate(order.getOrderSubstate());
        //组装协议
        if(contract.getCargoType()!=null){
            Result<Map<String,Object>> dictItem= frontInterface.getDictItemByItemId(contract.getCargoType());
            if(dictItem.isSuccess()){
                Map<String,Object> item=dictItem.getResult();
                hktsContractOnPCVo.setCargoTypeName(item.get("cargoTypeName").toString());
                hktsContractOnPCVo.setAgreementId(item.get("id").toString());
                hktsContractOnPCVo.setAgreementName(item.get("agreementName").toString());
            }
        }
        return hktsContractOnPCVo;
    }
}
